package com.wangxiaoxuan.seckill.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.wangxiaoxuan.seckill.pojo.Order;
import com.wangxiaoxuan.seckill.pojo.SecKillMessage;
import com.wangxiaoxuan.seckill.pojo.SeckillOrder;
import com.wangxiaoxuan.seckill.pojo.User;
import com.wangxiaoxuan.seckill.service.IGoodsService;
import com.wangxiaoxuan.seckill.service.IOrderService;
import com.wangxiaoxuan.seckill.service.ISeckillOrderService;
import com.wangxiaoxuan.seckill.vo.GoodsVo;
import com.wangxiaoxuan.seckill.vo.ResBeanEnum;
import com.wangxiaoxuan.seckill.vo.RespBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author 王小轩
 * @version 1.0
 * 秒杀controller
 */
@Controller
@RequestMapping("/secKill")
public class SecKillController implements InitializingBean {
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private ISeckillOrderService seckillOrderService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private RedisTemplate redisTemplate;

    private Map<Long,Boolean> EmptyStock=new HashMap<>();

    @RequestMapping("/{path}/doSecKill")
    public RespBean doSecKill(String path, User user,Long goodsId){
        //如果用户
        if (user == null){
            return RespBean.error(ResBeanEnum.SESSION_ERROR);
        }
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //获取秒杀接口地址是否正确
      Boolean isTure = orderService.checkPath(user,goodsId,path);
      if (!isTure){
          //路径不对
          return RespBean.error(ResBeanEnum.PATH_NOT_MATCH);
      }
        //判断订单
        SeckillOrder seckillOrder =
                seckillOrderService.getOne(new QueryWrapper<SeckillOrder>().eq("user_id", user.getId()).eq("goods_id", goodsId));
        if(seckillOrder!=null){
            //订单不为空说明该用户抢过了
            return RespBean.error(ResBeanEnum.REPEAT_ERROR);
        }
        //使用内存标记当redis库存为空时不再访问redis，减少redis压力
        if (EmptyStock.get(goodsId)){
            return RespBean.error(ResBeanEnum.EMPTY_STOCK);
        }
        //预减库存
        Long stock = valueOperations.decrement("seckillGoods" + goodsId);
        if (stock<0){
            EmptyStock.put(goodsId,true);
            valueOperations.increment("seckillGoods"+goodsId);
            return RespBean.error(ResBeanEnum.EMPTY_STOCK);
        }
            //下单
        SecKillMessage secKillMessage = new SecKillMessage(user, goodsId);

        return RespBean.success();
//        //存在则存起来
//        model.addAttribute("user",user);
//        //在后台判断库存
//        GoodsVo goodsVo = goodsService.findGoodsVoByGoodsId(goodsId);
//        if ((goodsVo.getStockCount()<1)){
//            //跳转失败页面
//            model.addAttribute("errmsg", ResBeanEnum.EMPTY_STOCK.getMessage());
//            return "secKillFail";
//        }
//        //判断订单
//        SeckillOrder seckillOrder =
//                seckillOrderService.getOne(new QueryWrapper<SeckillOrder>().eq("user_id", user.getId()).eq("goods_id", goodsId));
//        if(seckillOrder!=null){
//            //订单不为空说明该用户抢过了
//            model.addAttribute("errmsg",ResBeanEnum.REPEAT_ERROR);
//            return "secKillFail";
//        }
//        //抢购
//        Order order=orderService.seckill(user,goodsVo);//秒杀生成订单
//        model.addAttribute("order",order);//放入
//        model.addAttribute("goods",goodsVo);//放入物品
//        return "orderDetail";
    }

    /**
     * 获取秒杀地址
     * @param user
     * @param goodsId
     * @return
     */
    @GetMapping("/path")
    @ResponseBody
    public RespBean GetPath(User user, Long goodsId,String captcha, HttpServletRequest request){
        if (user==null){
            return RespBean.error(ResBeanEnum.SESSION_ERROR);
        }
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //限流5s访问5次
        String uri = request.getRequestURI();
        captcha="0";
        Integer count = (Integer) valueOperations.get(uri + ":" + user.getId());
        if (count==0){
            valueOperations.set(uri+":"+user.getId(),1,5, TimeUnit.SECONDS);
        }else if (count<5){
            valueOperations.increment(uri+":"+user.getId());
        }else {
            return RespBean.error(ResBeanEnum.ACCESS_LIMIT);
        }
        String path=orderService.createPath(user,goodsId);
        return RespBean.success(path);
    }



    /**
     * 初始化方法,初始化时将商品数量加载到redis
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        List<GoodsVo> list = goodsService.findGoodsVo();
        if (CollectionUtils.isEmpty(list)){
            return;
        }
        list.forEach(goodsVo -> {
            redisTemplate.opsForValue().set("seckillGoods"+goodsVo.getId(),goodsVo.getStockCount());
            //有库存
            EmptyStock.put(goodsVo.getId(),false);
        });
    }
}
